﻿/* EntitiesToDTOs. Copyright (c) 2011. Fabian Fernandez.
 * http://entitiestodtos.codeplex.com
 * Licensed by Common Development and Distribution License (CDDL).
 * http://entitiestodtos.codeplex.com/license
 * Fabian Fernandez. 
 * http://www.linkedin.com/in/fabianfernandezb/en
 * */
using EnvDTE;
using EnvDTE80;
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Xml.Linq;
using System.Threading;
using EntitiesToDTOs.Enums;
using EntitiesToDTOs.Events;
using EntitiesToDTOs.Generators;
using EntitiesToDTOs.Generators.Parameters;
using EntitiesToDTOs.Helpers;
using EntitiesToDTOs.Properties;
using Microsoft.VisualStudio.Shell;

namespace EntitiesToDTOs.UI
{
    /// <summary>
    /// Main Window of the AddIn
    /// </summary>
    public partial class MainWindow : Form
    {
        /// <summary>
        /// Represents the IDE (Visual Studio)
        /// </summary>
        private DTE2 _applicationObject;

        /// <summary>
        /// Reference to the ProgressWindow used to show the process progress
        /// </summary>
        private GenerationProgressWindow ProgressWindow { get; set; }

        // Column indexes of types grid
        private int TypeCellWarnings = 0;
        private int TypeCellName = 1;
        private int TypeCellType = 2;
        private int TypeCellGenerate = 3;

        /// <summary>
        /// Transparent image.
        /// </summary>
        private Bitmap TransparentImage
        {
            get
            {
                if (_transparentImage == null)
                {
                    _transparentImage = new Bitmap(22, 22);
                    Graphics graphics = Graphics.FromImage(_transparentImage);
                    graphics.FillRectangle(Brushes.Transparent, 0, 0, 22, 22);
                    graphics.Dispose();
                }

                return _transparentImage;
            }
        }
        private Bitmap _transparentImage = null;

        /// <summary>
        /// Current EDMX document.
        /// </summary>
        private XDocument CurrentEdmxDocument
        {
            get
            {
                // Validate EDMX
                if (this.lstEdmxFiles.SelectedItem != null)
                {
                    // Get the EDMX Document as ProjectItem
                    var edmxProjectItem = (this.lstEdmxFiles.SelectedItem as ProjectItem);

                    if (edmxProjectItem.Name != _currentEdmxDocumentName)
                    {
                        _currentEdmxDocumentName = edmxProjectItem.Name;

                        // Get the EDMX Document
                        _currentEdmxDocument = EdmxHelper.GetEdmxDocument(edmxProjectItem);
                    }
                }
                else
                {
                    _currentEdmxDocument = null;
                    _currentEdmxDocumentName = null;
                }

                return _currentEdmxDocument;
            }
        }
        private XDocument _currentEdmxDocument = null;
        private string _currentEdmxDocumentName = null;



        /// <summary>
        /// Creates a new instance of MainWindow
        /// </summary>
        /// <param name="applicationObject"></param>
        public MainWindow(DTE2 applicationObject)
        {
            InitializeComponent();

            try
            {
                // Set Window Caption
                this.Text = string.Format(Resources.MainWindow_Caption, AssemblyHelper.Version);

                // Set the object that represents the IDE (Visual Studio)
                _applicationObject = applicationObject;

                // Check if there is an open Solution
                if (VisualStudioHelper.IsSolutionOpen(_applicationObject) == false)
                {
                    MessageHelper.ShowErrorMessage(Resources.Error_NoSolution);
                }
                else
                {
                    // Clear event handlers of GeneratorManager
                    GeneratorManager.ClearEventHandlers();

                    // Initialize EdmxHelper
                    EdmxHelper.Initialize();

                    // Initialize custom header comment control
                    this.InitCustomHeaderComment();

                    // Set UI Events that do not depend of any initialization
                    this.chbGenerateAllTypes.CheckedChanged += this.chbGenerateAllTypes_CheckedChanged;
                    this.chbGenerateComplexTypes.CheckedChanged += this.chbGenerateComplexTypes_CheckedChanged;
                    this.chbGenerateEntityTypes.CheckedChanged += this.chbGenerateEntityTypes_CheckedChanged;
                    this.dgvTypes.CellContentClick += this.dgvTypes_CellContentClick;

                    // Get the Solution Items
                    List<ProjectItem> solutionItems = 
                        VisualStudioHelper.GetSolutionProjectItems(_applicationObject.Solution);

                    // Get the EDMX Project Items
                    List<ProjectItem> edmxItems = solutionItems
                        .Where(i => i.Name.EndsWith(Resources.EdmxFileExtension))
                        .OrderBy(i => i.Name).ToList();

                    // lstEdmxFiles
                    this.lstEdmxFiles.SelectedIndexChanged += this.lstEdmxFiles_SelectedIndexChanged;
                    this.lstEdmxFiles.DisplayMember = Resources.ProjectItem_Name;
                    this.lstEdmxFiles.DataSource = edmxItems;
                    if (this.lstEdmxFiles.Items.Count > 0)
                    {
                        this.lstEdmxFiles.SelectedIndex = 0;
                    }

                    // Get Solution Projects
                    List<Project> solutionProjects = 
                        VisualStudioHelper.GetProjectsFromSolution(_applicationObject.Solution);

                    // lstProjectsDTOs
                    this.lstProjectsDTOs.DataSource = solutionProjects;
                    this.lstProjectsDTOs.DisplayMember = Resources.ProjectItem_Name;

                    // lstProjectsAssemblers
                    this.lstProjectsAssemblers.DataSource = solutionProjects.ToList();
                    this.lstProjectsAssemblers.DisplayMember = Resources.ProjectItem_Name;

                    // cbLogProcess
                    this.cbLogProcess.Checked = LogManager.IsLogActive;

                    // Attach to GeneratorManager events
                    GeneratorManager.OnComplete += this.GeneratorManager_OnComplete;
                    GeneratorManager.OnCancel += this.GeneratorManager_OnCancel;
                    GeneratorManager.OnException += this.GeneratorManager_OnException;

                    // Load latest user configuration
                    this.LoadLatestConfiguration();
                }
            }
            catch (Exception ex)
            {
                MessageHelper.ShowErrorMessage(ex.Message);
            }
        }

        #region UI Events

        /// <summary>
        /// Executed when the window is about to be closed.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void MainWindow_FormClosing(object sender, FormClosingEventArgs e)
        {
            VisualStudioHelper.SetStatusBarMessage(Resources.Info_Ready);
        }

        /// <summary>
        /// Executed when the selected index of lstEdmxFiles changes.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void lstEdmxFiles_SelectedIndexChanged(object sender, EventArgs e)
        {
            this.UpdateCustomizeEdmx();
        }

        /// <summary>
        /// Executed when the User checks the Custom Header Comment checkbox
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void cbCustomHeaderComment_CheckedChanged(object sender, EventArgs e)
        {
            this.txtCustomHeaderComment.Enabled = this.cbCustomHeaderComment.Checked;
        }

        /// <summary>
        /// Executed when the User checks the Generate Assemblers checkbox.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void cbGenerateAssemblers_CheckedChanged(object sender, EventArgs e)
        {
            this.ToggleGenerateAssemblers(this.cbGenerateAssemblers.Checked);
        }

        /// <summary>
        /// Executed when the User checks the Log process checkbox
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void cbLogProcess_CheckedChanged(object sender, EventArgs e)
        {
            LogManager.IsLogActive = this.cbLogProcess.Checked;

            if (this.cbLogProcess.Checked)
            {
                // TODO: ffernandez, Prompt the user to indicate where to store the log
                MessageBox.Show(string.Format(Resources.Info_LogFile, Resources.LogFilePath),
                    Resources.Info_Caption, MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }

        /// <summary>
        /// Executed when the User checks the Use Default Namespace checkbox of Assemblers.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void cbUseDefaultNamespaceAssemblers_CheckedChanged(object sender, EventArgs e)
        {
            if (this.cbUseDefaultNamespaceAssemblers.Checked)
            {
                Project targetProject = this.GetSelectedProject(this.lstProjectsAssemblers);

                this.txtNamespaceAssemblers.Enabled = false;
                this.txtNamespaceAssemblers.Text = VisualStudioHelper.GetProjectDefaultNamespace(targetProject);
            }
            else
            {
                this.txtNamespaceAssemblers.Enabled = true;
            }
        }

        /// <summary>
        /// Executed when the User checks the Use Default Namespace checkbox of DTOs.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void cbUseDefaultNamespaceDTOs_CheckedChanged(object sender, EventArgs e)
        {
            if (this.cbUseDefaultNamespaceDTOs.Checked)
            {
                Project targetProject = this.GetSelectedProject(this.lstProjectsDTOs);

                this.txtNamespaceDTOs.Enabled = false;
                this.txtNamespaceDTOs.Text = VisualStudioHelper.GetProjectDefaultNamespace(targetProject);
            }
            else
            {
                this.txtNamespaceDTOs.Enabled = true;
            }
        }
        
        /// <summary>
        /// Executed when the User clicks the Close button
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void btnCancel_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        /// <summary>
        /// Executed when the User clicks the Generate button
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void btnGenerate_Click(object sender, EventArgs e)
        {
            this.Generate();
        }

        /// <summary>
        /// Executed when the User clicks the Help button.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void btnHelp_Click(object sender, EventArgs e)
        {
            var helpWin = new HelpWindow();
            helpWin.ShowDialog(this);
        }

        /// <summary>
        /// Executed when the User enters the Help button
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void btnHelp_MouseEnter(object sender, EventArgs e)
        {
            this.btnHelp.Image = Resources.img_help_hover;
        }

        /// <summary>
        /// Executed when the User leaves the Help button.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void btnHelp_MouseLeave(object sender, EventArgs e)
        {
            this.btnHelp.Image = Resources.img_help;
        }

        /// <summary>
        /// Executed when the User selects a Project from the list of Projects for Assemblers.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void lstProjectsAssemblers_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (this.lstProjectsAssemblers.SelectedItem != null
                && this.cbUseDefaultNamespaceAssemblers.Checked)
            {
                Project targetProject = this.GetSelectedProject(this.lstProjectsAssemblers);

                this.txtNamespaceAssemblers.Text = VisualStudioHelper.GetProjectDefaultNamespace(targetProject);
            }
        }

        /// <summary>
        /// Executed when the User selects a Project from the list of Projects for DTOs.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void lstProjectsDTOs_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (this.lstProjectsDTOs.SelectedItem != null
                && this.cbUseDefaultNamespaceDTOs.Checked)
            {
                Project targetProject = this.GetSelectedProject(this.lstProjectsDTOs);

                this.txtNamespaceDTOs.Text = VisualStudioHelper.GetProjectDefaultNamespace(targetProject);
            }
        }

        /// <summary>
        /// Executed when the User checks one of the Source File Generation Type radio buttons for Assemblers.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void rbSourceFileGenerationTypeAssemblers_CheckedChanged(object sender, EventArgs e)
        {
            if (this.rbOneSourceFileAssemblers.Checked)
            {
                this.txtSourceFileNameAssemblers.Enabled = true;
                this.txtSourceFileNameAssemblers.Text = string.Empty;
            }
            else
            {
                this.txtSourceFileNameAssemblers.Enabled = false;
                this.txtSourceFileNameAssemblers.Text = Resources.Text_DefaultSourceFileName;
            }
        }

        /// <summary>
        /// Executed when the User checks one of the Source File Generation Type radio buttons for DTOs.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void rbSourceFileGenerationTypeDTOs_CheckedChanged(object sender, EventArgs e)
        {
            if (this.rbOneSourceFileDTOs.Checked)
            {
                this.txtSourceFileNameDTOs.Enabled = true;
                this.txtSourceFileNameDTOs.Text = string.Empty;
            }
            else
            {
                this.txtSourceFileNameDTOs.Enabled = false;
                this.txtSourceFileNameDTOs.Text = Resources.Text_DefaultSourceFileName;
            }
        }

        /// <summary>
        /// Executed when the User clicks the Config Export menu button.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnConfigExport_Click(object sender, EventArgs e)
        {
            try
            {
                // Validate generation process
                this.ValidateGeneration();

                // Show Save File Dialog
                var dialog = new SaveFileDialog();
                dialog.Filter = Resources.EntitiesToDTOsConfigFileFilter;
                if (dialog.ShowDialog() == DialogResult.OK)
                {
                    // Export configuration
                    ConfigurationHelper.Export(this.GetGeneratorManagerParams(), dialog.FileName);

                    // Show OK message
                    VisualStudioHelper.SetStatusBarMessage(Resources.Info_ConfigExportComplete);
                }
            }
            catch (Exception ex)
            {
                this.ManageException(ex);
            }
        }

        /// <summary>
        /// Executed when the User clicks the Config Import menu button.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnConfigImport_Click(object sender, EventArgs e)
        {
            try
            {
                // Show Open File Dialog
                var dialog = new OpenFileDialog();
                dialog.Filter = Resources.EntitiesToDTOsConfigFileFilter;
                if (dialog.ShowDialog() == DialogResult.OK)
                {
                    // Load the configuration
                    bool showWarnings = true;
                    this.LoadConfiguration(dialog.FileName, showWarnings);

                    // Validate generation process
                    this.ValidateGeneration();

                    // Shoe OK message
                    VisualStudioHelper.SetStatusBarMessage(Resources.Info_ConfigImportComplete);
                }
            }
            catch (Exception ex)
            {
                this.ManageException(ex);
            }
        }

        /// <summary>
        /// Executed when the user clicks the generate all types checkbox.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void chbGenerateAllTypes_CheckedChanged(object sender, EventArgs e)
        {
            bool isChecked = this.chbGenerateAllTypes.Checked;

            this.chbGenerateComplexTypes.Checked = isChecked;
            this.chbGenerateEntityTypes.Checked = isChecked;

            this.UpdateGenerateAllTypesCheckedState();

            // Checks warnings in types to generate
            this.CheckTypesWarnings();
        }
        
        /// <summary>
        /// Executed when the user clicks the generate complex types checkbox.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void chbGenerateComplexTypes_CheckedChanged(object sender, EventArgs e)
        {
            this.UpdateGenerateAllTypesCheckedState();

            foreach (DataGridViewRow row in this.dgvTypes.Rows)
            {
                if ((string)row.Cells[TypeCellType].Value == "Complex")
                {
                    row.Cells[TypeCellGenerate].Value = this.chbGenerateComplexTypes.Checked;
                }
            }

            // Checks warnings in types to generate
            this.CheckTypesWarnings();
        }

        /// <summary>
        /// Executed when the user clicks the generate entity types checkbox.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void chbGenerateEntityTypes_CheckedChanged(object sender, EventArgs e)
        {
            this.UpdateGenerateAllTypesCheckedState();

            foreach (DataGridViewRow row in this.dgvTypes.Rows)
            {
                if ((string)row.Cells[TypeCellType].Value == "Entity")
                {
                    row.Cells[TypeCellGenerate].Value = this.chbGenerateEntityTypes.Checked;
                }
            }

            // Checks warnings in types to generate
            this.CheckTypesWarnings();
        }

        /// <summary>
        /// Executed when cell content of types grid is clicked.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void dgvTypes_CellContentClick(object sender, DataGridViewCellEventArgs e)
        {
            if (e.ColumnIndex == TypeCellGenerate)
            {
                this.UpdateGenerateTypesCheckedState();

                // Checks warnings in types to generate
                this.CheckTypesWarnings();
            }
        }

        /// <summary>
        /// Executed when dto identifier "none" option checked status changes.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void rbDTOIdentifierNone_CheckedChanged(object sender, EventArgs e)
        {
            this.txtDTOIdentifierWord.Enabled = (rbDTOIdentifierNone.Checked == false);
        }

        /// <summary>
        /// Executed when assembler identifier "none" option checked status changes.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void rbAssemblerIdentifierNone_CheckedChanged(object sender, EventArgs e)
        {
            this.txtAssemblerIdentifierWord.Enabled = (rbAssemblerIdentifierNone.Checked == false);
        }

        #endregion UI Events

        #region GeneratorManager Events

        /// <summary>
        /// Executed when an Exception is raised by the GeneratorManager.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void GeneratorManager_OnException(object sender, GeneratorOnExceptionEventArgs e)
        {
            this.ManageException(e.Exception);
        }

        /// <summary>
        /// Executed when a Cancel event is raised by the GeneratorManager.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void GeneratorManager_OnCancel(object sender, GeneratorOnCancelEventArgs e)
        {
            this.Enabled = true;
        }

        /// <summary>
        /// Executed when the GeneratorManager finishes the process.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void GeneratorManager_OnComplete(object sender, GeneratorOnCompleteEventArgs e)
        {
            // Close progress window
            this.ProgressWindow.Close();

            // Check Warnings
            if (VisualStudioHelper.ErrorTaskCollectionHasItems())
            {
                // Show Warning message
                MessageBox.Show(Resources.Info_GenerationCompleteWithWarnings, Resources.Info_Caption,
                    MessageBoxButtons.OK, MessageBoxIcon.Warning);

                // Show ErrorList pane
                VisualStudioHelper.ShowErrorList();
            }
            else
            {
                // Show OK message
                MessageBox.Show(Resources.Info_GenerationComplete, Resources.Info_Caption, 
                    MessageBoxButtons.OK, MessageBoxIcon.Information);
            }

            // Release COM Object (use ReleaseComObject only if it is absolutely required)
            //System.Runtime.InteropServices.Marshal.ReleaseComObject(_applicationObject);

            // Close AddIn
            this.Close();
        }

        #endregion GeneratorManager Events

        #region Methods

        /// <summary>
        /// Initializes the custom header comment control.
        /// </summary>
        private void InitCustomHeaderComment()
        {
            // Get IDE text editor comment colors
            ColorableItems ci = VisualStudioHelper.GetTextEditorCommentColorableItems();

            // Set background color
            int oleColor = Convert.ToInt32(ci.Background);
            Color color = ColorTranslator.FromOle(oleColor);
            this.txtCustomHeaderComment.BackColor = color;

            // Set foreground color
            oleColor = Convert.ToInt32(ci.Foreground);
            color = ColorTranslator.FromOle(oleColor);
            this.txtCustomHeaderComment.ForeColor = color;

            // Set normal or bold text
            this.txtCustomHeaderComment.Font = new Font(this.txtCustomHeaderComment.Font, 
                ci.Bold ? FontStyle.Bold : FontStyle.Regular);
        }

        /// <summary>
        /// Updates the checked state of the generate types filters.
        /// </summary>
        private void UpdateGenerateTypesCheckedState()
        {
            bool generateComplexTypesAll = true;
            bool generateComplexTypesSome = false;
            bool generateEntityTypesAll = true;
            bool generateEntityTypesSome = false;

            foreach (DataGridViewRow row in this.dgvTypes.Rows)
            {
                if ((string)row.Cells[TypeCellType].Value == "Complex")
                {
                    if ((bool)row.Cells[TypeCellGenerate].EditedFormattedValue == false)
                    {
                        generateComplexTypesAll = false;
                    }
                    else
                    {
                        generateComplexTypesSome = true;
                    }
                }
                else
                {
                    if ((bool)row.Cells[TypeCellGenerate].EditedFormattedValue == false)
                    {
                        generateEntityTypesAll = false;
                    }
                    else
                    {
                        generateEntityTypesSome = true;
                    }
                }
            }

            this.chbGenerateComplexTypes.CheckedChanged -= this.chbGenerateComplexTypes_CheckedChanged;
            this.chbGenerateComplexTypes.CheckState =
                (generateComplexTypesAll == true ? CheckState.Checked : CheckState.Unchecked);
            if (generateComplexTypesAll == false && generateComplexTypesSome == true)
            {
                this.chbGenerateComplexTypes.CheckState = CheckState.Indeterminate;
            }
            this.chbGenerateComplexTypes.CheckedChanged += this.chbGenerateComplexTypes_CheckedChanged;

            this.chbGenerateEntityTypes.CheckedChanged -= this.chbGenerateEntityTypes_CheckedChanged;
            this.chbGenerateEntityTypes.CheckState =
                (generateEntityTypesAll == true ? CheckState.Checked : CheckState.Unchecked);
            if (generateEntityTypesAll == false && generateEntityTypesSome == true)
            {
                this.chbGenerateEntityTypes.CheckState = CheckState.Indeterminate;
            }
            this.chbGenerateEntityTypes.CheckedChanged += this.chbGenerateEntityTypes_CheckedChanged;

            this.UpdateGenerateAllTypesCheckedState();
        }

        /// <summary>
        /// Updates the checked state of the generate all types option.
        /// </summary>
        private void UpdateGenerateAllTypesCheckedState()
        {
            this.chbGenerateAllTypes.CheckedChanged -= this.chbGenerateAllTypes_CheckedChanged;

            if (this.chbGenerateComplexTypes.CheckState == CheckState.Checked
                && this.chbGenerateEntityTypes.CheckState == CheckState.Checked)
            {
                this.chbGenerateAllTypes.CheckState = CheckState.Checked;
            }
            else if (this.chbGenerateComplexTypes.CheckState == CheckState.Checked
                || this.chbGenerateEntityTypes.CheckState == CheckState.Checked
                || this.chbGenerateComplexTypes.CheckState == CheckState.Indeterminate
                || this.chbGenerateEntityTypes.CheckState == CheckState.Indeterminate)
            {
                this.chbGenerateAllTypes.CheckState = CheckState.Indeterminate;
            }
            else
            {
                this.chbGenerateAllTypes.CheckState = CheckState.Unchecked;
            }

            this.chbGenerateAllTypes.CheckedChanged += this.chbGenerateAllTypes_CheckedChanged;
        }

        /// <summary>
        /// Gets the Selected Project from the list of Projects
        /// </summary>
        /// <returns></returns>
        private Project GetSelectedProject(ListBox listBox)
        {
            return (listBox.SelectedItem as Project);
        }

        /// <summary>
        /// In case of Exception, this method must be call.
        /// </summary>
        private void ManageException(Exception ex)
        {
            LogManager.LogError(ex);

            if (this.ProgressWindow != null)
            {
                // Close progress window
                this.ProgressWindow.Close();
            }

            MessageHelper.ShowErrorMessage(ex.Message);

            this.Enabled = true;
        }

        /// <summary>
        /// Updates Customize EDMX panel based on the current edmx file selected.
        /// </summary>
        private void UpdateCustomizeEdmx()
        {
            try
            {
                // Clear types to generate
                this.dgvTypes.Rows.Clear();

                // Validate EDMX
                if (this.lstEdmxFiles.SelectedItem != null)
                {
                    // Get Complex Types
                    List<XElement> allTypes = EdmxHelper.GetComplexTypeNodes(this.CurrentEdmxDocument).ToList();

                    // Get Entity Types
                    allTypes.AddRange(EdmxHelper.GetEntityTypeNodes(this.CurrentEdmxDocument));

                    // Order types by name
                    allTypes = allTypes.OrderBy(e => e.Attribute(EdmxNodeAttributes.EntityType_Name).Value).ToList();

                    // Add types to panel
                    int rowIndex = 0;
                    foreach(XElement type in allTypes)
                    {
                        // Add row
                        rowIndex = this.dgvTypes.Rows.Add();

                        // Set type name
                        this.dgvTypes.Rows[rowIndex].Cells[TypeCellName].Value =
                            type.Attribute(EdmxNodeAttributes.EntityType_Name).Value;

                        // Set type
                        this.dgvTypes.Rows[rowIndex].Cells[TypeCellType].Value =
                            (type.Name == EdmxNodes.EntityType ? "Entity" : "Complex");

                        // Set generate value
                        this.dgvTypes.Rows[rowIndex].Cells[TypeCellGenerate].Value = true;

                        // Set warnings cell, no image
                        this.dgvTypes.Rows[rowIndex].Cells[TypeCellWarnings].Value = this.TransparentImage;
                    }

                    // Update filter checked states and check warnings
                    this.UpdateGenerateTypesCheckedState();

                } // END if...
            }
            catch (Exception ex)
            {
                this.ManageException(ex);
            }
        }

        /// <summary>
        /// Checks warnings in types to generate.
        /// </summary>
        private void CheckTypesWarnings()
        {
            // Get entity nodes
            IEnumerable<XElement> entityNodes = 
                EdmxHelper.GetEntityTypeNodes(this.CurrentEdmxDocument);

            // Get navigation nodes
            IEnumerable<XElement> navigationNodes = 
                EdmxHelper.GetNavigationPropertyNodes(this.CurrentEdmxDocument);

            // Get association nodes
            IEnumerable<XElement> associationNodes =
                EdmxHelper.GetAssociationNodes(this.CurrentEdmxDocument);

            // Get the rows collection to query
            IEnumerable<DataGridViewRow> rowsCollection =
                this.dgvTypes.Rows.OfType<DataGridViewRow>();
            
            // Loop through rows
            foreach (DataGridViewRow row in this.dgvTypes.Rows)
            {
                bool showWarnings = false;
                string warningText = string.Empty;

                // Check for warnings only if it is an entity and is going to be generated
                if ((string)row.Cells[TypeCellType].Value == "Entity"
                    && (bool)row.Cells[TypeCellGenerate].EditedFormattedValue == true)
                {
                    // Get the entity node
                    XElement rowEntityNode = entityNodes.First(n =>
                        n.Attribute(EdmxNodeAttributes.EntityType_Name).Value
                        == (string)row.Cells[TypeCellName].Value);

                    // Get the base type name (if exists)
                    string baseTypeName = EdmxHelper.GetEntityBaseType(rowEntityNode);

                    if (string.IsNullOrWhiteSpace(baseTypeName) == false)
                    {
                        // Check if the base type is going to be generated
                        DataGridViewRow rowBase = rowsCollection.First(r =>
                            (string)r.Cells[TypeCellName].Value == baseTypeName);

                        if ((bool)rowBase.Cells[TypeCellGenerate].EditedFormattedValue == false)
                        {
                            // Base type is not generated, add warning
                            showWarnings = true;
                            warningText += Environment.NewLine
                                + string.Format(Resources.Warning_BaseTypeNotGenerated,
                                rowBase.Cells[TypeCellName].Value);
                        }
                    }

                    // Get navigations of this entity
                    IEnumerable<XElement> entityNavigations = navigationNodes.Where(n => 
                        n.Parent.Attribute(EdmxNodeAttributes.EntityType_Name).Value
                        == (string)row.Cells[TypeCellName].Value);

                    foreach (XElement navNode in entityNavigations)
                    {
                        // Get toRole attribute value
                        string toRole = navNode.Attribute(
                            EdmxNodeAttributes.NavigationProperty_ToRole).Value;

                        // Get the association name
                        string associationName = EdmxHelper.GetNavigationAssociationName(navNode);

                        // Get the association node
                        XElement assocNode = associationNodes.First(n => 
                            n.Attribute(EdmxNodeAttributes.Association_Name).Value == associationName);

                        // Get destination type name
                        string destinationTypeName = assocNode.Descendants(EdmxNodes.End).First(n =>
                            n.Attribute(EdmxNodeAttributes.End_Role).Value == toRole)
                            .Attribute(EdmxNodeAttributes.End_Type).Value;

                        // Remove namespace from destination type name
                        destinationTypeName = EdmxHelper.GetNameWithoutNamespace(destinationTypeName);

                        // Check if destination type is going to be generated
                        DataGridViewRow rowDestination = rowsCollection.First(r =>
                            (string)r.Cells[TypeCellName].Value == destinationTypeName);

                        if ((bool)rowDestination.Cells[TypeCellGenerate].EditedFormattedValue == false)
                        {
                            // Destination type is not generated, add warning
                            showWarnings = true;
                            warningText += Environment.NewLine
                                + string.Format(Resources.Warning_DestTypeNotGenerated,
                                rowDestination.Cells[TypeCellName].Value);
                        }
                    }
                }

                if (showWarnings == true)
                {
                    // Add header to warning text and set image
                    warningText = ("Warning" + warningText);
                    row.Cells[TypeCellWarnings].Value = Resources.img_warning;
                }
                else
                {
                    // Set no image
                    row.Cells[TypeCellWarnings].Value = this.TransparentImage;
                }

                // Set warning text
                row.Cells[TypeCellWarnings].ToolTipText = warningText;
            }
        }

        /// <summary>
        /// Validates the Edmx source.
        /// </summary>
        private void ValidateEdmxSource()
        {
            if (this.lstEdmxFiles.SelectedItem == null)
            {
                throw new InvalidOperationException(Resources.Error_NoEDMXSource);
            }
        }

        /// <summary>
        /// Process validations to check if the AddIn is ready to start the generation.
        /// </summary>
        private void ValidateGeneration()
        {
            #region DTOs validations
            if (this.rbSourceEdmx.Checked == true)
            {
                // Generate from model

                // Validate EDMX
                this.ValidateEdmxSource();

                // Check if at least one type is marked to be generated
                if (this.chbGenerateAllTypes.CheckState == CheckState.Unchecked)
                {
                    throw new InvalidOperationException(Resources.Error_NoTypesToGenerateFrom);
                }
            }

            if (this.lstProjectsDTOs.SelectedItem == null)
            {
                throw new InvalidOperationException(Resources.Error_NoTargetProjectDTOs);
            }
            else if (string.IsNullOrWhiteSpace(this.GetSourceFileNamespaceForDTOs()))
            {
                throw new InvalidOperationException(Resources.Error_InvalidNamespaceDTOs);
            }

            // Check the Source File Generation Type for DTOs
            if (this.rbOneSourceFileDTOs.Checked)
            {
                if (string.IsNullOrWhiteSpace(this.txtSourceFileNameDTOs.Text)
                    || this.txtSourceFileNameDTOs.Text.Contains(Resources.Space))
                {
                    throw new InvalidOperationException(Resources.Error_InvalidSourceFileNameDTOs);
                }
            }

            // Check identifier
            if (this.rbDTOIdentifierPrefix.Checked == true || this.rbDTOIdentifierSuffix.Checked == true)
            {
                if (string.IsNullOrWhiteSpace(this.txtDTOIdentifierWord.Text) == true)
                {
                    throw new InvalidOperationException(Resources.Error_IdentifierWordEmpty);
                }
            }
            #endregion DTOs validations

            #region Assemblers validations
            if (this.cbGenerateAssemblers.Checked)
            {
                if (this.lstProjectsAssemblers.SelectedItem == null)
                {
                    throw new InvalidOperationException(Resources.Error_NoTargetProjectAssemblers);
                }
                else if (string.IsNullOrWhiteSpace(this.GetSourceFileNamespaceForAssemblers()))
                {
                    throw new InvalidOperationException(Resources.Error_InvalidNamespaceAssemblers);
                }

                // Check the Source File Generation Type for Assemblers
                if (this.rbOneSourceFileAssemblers.Checked)
                {
                    if (string.IsNullOrWhiteSpace(this.txtSourceFileNameAssemblers.Text)
                        || this.txtSourceFileNameAssemblers.Text.Contains(Resources.Space))
                    {
                        throw new InvalidOperationException(Resources.Error_InvalidSourceFileNameAssemblers);
                    }
                }

                // Check identifier
                if (this.rbAssemblerIdentifierPrefix.Checked == true || this.rbAssemblerIdentifierSuffix.Checked == true)
                {
                    if (string.IsNullOrWhiteSpace(this.txtAssemblerIdentifierWord.Text) == true)
                    {
                        throw new InvalidOperationException(Resources.Error_IdentifierWordEmpty);
                    }
                }
            }
            #endregion Assemblers validations
        }

        /// <summary>
        /// Gets the Source File Namespace for DTOs.
        /// </summary>
        /// <returns></returns>
        private string GetSourceFileNamespaceForDTOs()
        {
            // Get the target Project for DTOs
            Project targetProject = this.GetSelectedProject(this.lstProjectsDTOs);

            string sourceNamespace = null;
            if (this.cbUseDefaultNamespaceDTOs.Checked)
            {
                sourceNamespace = VisualStudioHelper.GetProjectDefaultNamespace(targetProject);
            }
            else
            {
                sourceNamespace = this.txtNamespaceDTOs.Text;
            }

            return sourceNamespace;
        }

        /// <summary>
        /// Gets the Source File Namespace for Assemblers.
        /// </summary>
        /// <returns></returns>
        private string GetSourceFileNamespaceForAssemblers()
        {
            // Get the target Project for Assemblers
            Project targetProject = this.GetSelectedProject(this.lstProjectsAssemblers);

            string sourceNamespace = null;
            if (this.cbUseDefaultNamespaceAssemblers.Checked)
            {
                sourceNamespace = VisualStudioHelper.GetProjectDefaultNamespace(targetProject);
            }
            else
            {
                sourceNamespace = this.txtNamespaceAssemblers.Text;
            }

            return sourceNamespace;
        }

        /// <summary>
        /// Toggles the UI elements related to Assembler generation.
        /// </summary>
        /// <param name="enabled"></param>
        private void ToggleGenerateAssemblers(bool enabled)
        {
            this.lstProjectsAssemblers.Enabled = enabled;
            this.cbUseDefaultNamespaceAssemblers.Enabled = enabled;
            this.txtNamespaceAssemblers.Enabled = enabled;
            this.groupGenerationTypeAssemblers.Enabled = enabled;
        }

        /// <summary>
        /// Gets the types from which to generate the DTOs.
        /// </summary>
        /// <param name="onlyFilteredTypes">Indicates if only filtered types 
        /// or all types checked to be generated must be returned.</param>
        /// <returns></returns>
        private List<string> GetTypesToGenerateFilter(bool onlyFilteredTypes)
        {
            // Get types to generate
            var types = this.dgvTypes.Rows.OfType<DataGridViewRow>()
                .Where(r => (bool)r.Cells[TypeCellGenerate].Value == true)
                .Select(r => new
                {
                    Name = (string)r.Cells[TypeCellName].Value,
                    Type = (string)r.Cells[TypeCellType].Value
                });

            if (onlyFilteredTypes == false)
            {
                return types.Select(t => t.Name).ToList();
            }
            else if (this.chbGenerateAllTypes.CheckState == CheckState.Checked)
            {
                // All types must be generated, there is no filter
                return new List<string>();
            }
            else
            {
                var result = new List<string>();

                // Get complex types if filtered
                if (this.chbGenerateComplexTypes.CheckState == CheckState.Indeterminate)
                {
                    result.AddRange(types.Where(t => t.Type == "Complex").Select(t => t.Name));
                }

                // Get entity types if filtered
                if (this.chbGenerateEntityTypes.CheckState == CheckState.Indeterminate)
                {
                    result.AddRange(types.Where(t => t.Type == "Entity").Select(t => t.Name));
                }

                return result;
            }
        }

        /// <summary>
        /// Executes the generation process.
        /// </summary>
        private void Generate()
        {
            try
            {
                // Validate generation process
                this.ValidateGeneration();

                // Disable Main Window
                this.Enabled = false;

                // Clear ErrorList pane from ErrorTask produced by EntitiesToDTOs
                VisualStudioHelper.ClearErrorList();

                // Get Generator Manager parameters
                GeneratorManagerParams generatorParams = this.GetGeneratorManagerParams();

                // Show progress window
                this.ProgressWindow = new GenerationProgressWindow(generatorParams.DTOsParams.EDMXProjectItem.Name);
                this.ProgressWindow.Show(this);

                // Save latest configuration
                ConfigurationHelper.Export(generatorParams, ConfigurationHelper.TempFilePath);

                // Get the types to generate filter (with all types)
                // after exporting since we use only filtered types to export
                generatorParams.DTOsParams.TypesToGenerateFilter = 
                    this.GetTypesToGenerateFilter(onlyFilteredTypes: false);

                // Start the generation
                GeneratorManager.Generate(generatorParams);
            }
            catch (Exception ex)
            {
                this.ManageException(ex);
            }
        }

        /// <summary>
        /// Gets the parameters for GeneratorManager.
        /// </summary>
        /// <returns></returns>
        private GeneratorManagerParams GetGeneratorManagerParams()
        {
            #region DTOs
            // Get the EDMX Document as ProjectItem
            var edmxProjectItem = (this.lstEdmxFiles.SelectedItem as ProjectItem);

            // Get the types to generate filter
            List<string> typesToGenerateFilter = this.GetTypesToGenerateFilter(onlyFilteredTypes: true);

            // Get Target Project
            Project targetProjectDTOs = this.GetSelectedProject(this.lstProjectsDTOs);
            
            // Get Source File Namespace
            string sourceNamespaceDTOs = this.GetSourceFileNamespaceForDTOs();

            // Get Source File Name
            string sourceFileNameDTOs = this.txtSourceFileNameDTOs.Text.Trim();

            // Get the Source File Generation Type for DTOs
            var sourceFileGenerationTypeDTOs = SourceFileGenerationTypeEnum.SourceFilePerClass;
            if (this.rbOneSourceFileDTOs.Checked)
            {
                sourceFileGenerationTypeDTOs = SourceFileGenerationTypeEnum.OneSourceFile;
            }

            // Get the Association Type
            var associationType = AssociationTypeEnum.KeyProperty;
            if (this.rbAssociationConfigUseClassTypes.Checked)
            {
                associationType = AssociationTypeEnum.ClassType;
            }

            // Set generate types flags
            bool generateAllTypes = (this.chbGenerateAllTypes.CheckState == CheckState.Checked);
            bool generateAllComplexTypes = (this.chbGenerateComplexTypes.CheckState == CheckState.Checked);
            bool generateAllEntityTypes = (this.chbGenerateEntityTypes.CheckState == CheckState.Checked);

            // Set Identifier
            ClassIdentifierUseEnum dtosClassIdentifierUse = ClassIdentifierUseEnum.None;
            string dtosClassIdentifierWord = string.Empty;
            if (this.rbDTOIdentifierPrefix.Checked == true)
            {
                dtosClassIdentifierUse = ClassIdentifierUseEnum.Prefix;
                dtosClassIdentifierWord = this.txtDTOIdentifierWord.Text.Trim();
            }
            else if (this.rbDTOIdentifierSuffix.Checked == true)
            {
                dtosClassIdentifierUse = ClassIdentifierUseEnum.Suffix;
                dtosClassIdentifierWord = this.txtDTOIdentifierWord.Text.Trim();
            }
            #endregion DTOs

            #region Assemblers
            // Get Target Project
            Project targetProjectAssemblers = this.GetSelectedProject(this.lstProjectsAssemblers);

            // Get Source File Namespace
            string sourceNamespaceAssemblers = this.GetSourceFileNamespaceForAssemblers();

            // Get Source File Name
            string sourceFileNameAssemblers = this.txtSourceFileNameAssemblers.Text.Trim();

            // Get the Source File Generation Type for Assemblers
            var sourceFileGenerationTypeAssemblers = SourceFileGenerationTypeEnum.SourceFilePerClass;
            if (this.rbOneSourceFileAssemblers.Checked)
            {
                sourceFileGenerationTypeAssemblers = SourceFileGenerationTypeEnum.OneSourceFile;
            }

            // Set Identifier
            ClassIdentifierUseEnum assemblersClassIdentifierUse = ClassIdentifierUseEnum.None;
            string assemblersClassIdentifierWord = string.Empty;
            if (this.rbAssemblerIdentifierPrefix.Checked == true)
            {
                assemblersClassIdentifierUse = ClassIdentifierUseEnum.Prefix;
                assemblersClassIdentifierWord = this.txtAssemblerIdentifierWord.Text.Trim();
            }
            else if (this.rbAssemblerIdentifierSuffix.Checked == true)
            {
                assemblersClassIdentifierUse = ClassIdentifierUseEnum.Suffix;
                assemblersClassIdentifierWord = this.txtAssemblerIdentifierWord.Text.Trim();
            }
            #endregion Assemblers

            // Source File Header Comment
            string sourceFileHeaderComment = null;
            if (this.cbCustomHeaderComment.Checked)
            {
                sourceFileHeaderComment = this.txtCustomHeaderComment.Text;
            }

            // Set DTOs parameters
            var dtosParams = new GenerateDTOsParams(targetProjectDTOs, edmxProjectItem,
                typesToGenerateFilter, generateAllTypes, generateAllComplexTypes, generateAllEntityTypes,
                sourceFileHeaderComment, this.cbUseDefaultNamespaceDTOs.Checked, sourceNamespaceDTOs, 
                this.cbServiceReadyDTOs.Checked, dtosClassIdentifierUse, dtosClassIdentifierWord, 
                sourceFileGenerationTypeDTOs, sourceFileNameDTOs, associationType, 
                this.cbGenerateDTOConstructors.Checked);
            
            // Set Assemblers parameters
            var assemblersParams = new GenerateAssemblersParams(targetProjectAssemblers, 
                sourceFileHeaderComment, this.cbUseDefaultNamespaceAssemblers.Checked, 
                sourceNamespaceAssemblers, assemblersClassIdentifierUse, assemblersClassIdentifierWord, 
                sourceFileGenerationTypeAssemblers, sourceFileNameAssemblers, this.cbServiceReadyDTOs.Checked, 
                sourceNamespaceDTOs, targetProjectDTOs, edmxProjectItem);

            // Return the result generator parameters
            return new GeneratorManagerParams(dtosParams, assemblersParams, this.cbGenerateAssemblers.Checked);
        }

        /// <summary>
        /// Loads a configuration from the specified file path.
        /// </summary>
        /// <param name="filePath">File path from where to load the configuration.</param>
        /// <param name="showWarnings">Indicates if warnings should be shown.</param>
        /// <returns>True if EDMX Source match, DTOs Target Project match, Assemblers Target Project match. False otherwise.</returns>
        private bool LoadConfiguration(string filePath, bool showWarnings)
        {
            bool edmxSourceFound = false;
            bool dtosProjectFound = false;
            bool assemblersProjectFound = false;
            string warnings = string.Empty;

            // Import configuration
            GeneratorManagerParams config = ConfigurationHelper.Import(filePath);

            // Set EDMX Source
            foreach (ProjectItem projectItem in this.lstEdmxFiles.Items)
            {
                if (projectItem.Name == config.DTOsParams.EDMXName)
                {
                    this.lstEdmxFiles.SelectedItem = projectItem;
                    edmxSourceFound = true;
                    break;
                }
            }

            if (edmxSourceFound == false)
            {
                if (warnings.Length > 0) warnings += Environment.NewLine;
                warnings += string.Format(Resources.Warning_EdmxSourceNotFound, config.DTOsParams.EDMXName);
            }
            else
            {
                // Loop through types to generate
                foreach (DataGridViewRow row in this.dgvTypes.Rows)
                {
                    if (config.DTOsParams.GenerateAllTypes == true)
                    {
                        row.Cells[TypeCellGenerate].Value = true;
                    }
                    else
                    {
                        if ((config.DTOsParams.GenerateAllComplexTypes == false && (string)row.Cells[TypeCellType].Value == "Complex")
                            || (config.DTOsParams.GenerateAllEntityTypes == false && (string)row.Cells[TypeCellType].Value == "Entity"))
                        {
                            if (config.DTOsParams.TypesToGenerateFilter.Contains((string)row.Cells[TypeCellName].Value) == true)
                            {
                                row.Cells[TypeCellGenerate].Value = true;
                            }
                            else
                            {
                                row.Cells[TypeCellGenerate].Value = false;
                            }
                        }
                    }
                }

                // Update generate types filter state
                this.UpdateGenerateTypesCheckedState();
            }

            // Set Target Project for DTOs
            foreach (Project project in this.lstProjectsDTOs.Items)
            {
                if (project.Name == config.DTOsParams.TargetProjectName)
                {
                    this.lstProjectsDTOs.SelectedItem = project;
                    dtosProjectFound = true;
                    break;
                }
            }

            if (dtosProjectFound == false)
            {
                if (warnings.Length > 0) warnings += Environment.NewLine;
                warnings += string.Format(Resources.Warning_DTOsTargetProjectNotFound, config.DTOsParams.TargetProjectName);
            }

            // Set Target Project for Assemblers
            foreach (Project project in this.lstProjectsAssemblers.Items)
            {
                if (project.Name == config.AssemblersParams.TargetProjectName)
                {
                    this.lstProjectsAssemblers.SelectedItem = project;
                    assemblersProjectFound = true;
                    break;
                }
            }

            if (assemblersProjectFound == false)
            {
                if (warnings.Length > 0) warnings += Environment.NewLine;
                warnings += string.Format(Resources.Warning_AssemblersTargetProjectNotFound, config.AssemblersParams.TargetProjectName);
            }

            // Set Source File namespace for DTOs
            this.cbUseDefaultNamespaceDTOs.Checked = (config.DTOsParams.UseProjectDefaultNamespace && dtosProjectFound);
            if (this.cbUseDefaultNamespaceDTOs.Checked)
            {
                VisualStudioHelper.GetProjectDefaultNamespace(this.GetSelectedProject(this.lstProjectsDTOs));
            }
            else
            {
                this.txtNamespaceDTOs.Text = config.DTOsParams.SourceNamespace;
            }

            // Set Source File namespace for Assemblers
            this.cbUseDefaultNamespaceAssemblers.Checked = (config.AssemblersParams.UseProjectDefaultNamespace && assemblersProjectFound);
            if (this.cbUseDefaultNamespaceAssemblers.Checked)
            {
                VisualStudioHelper.GetProjectDefaultNamespace(this.GetSelectedProject(this.lstProjectsAssemblers));
            }
            else
            {
                this.txtNamespaceAssemblers.Text = config.AssemblersParams.SourceNamespace;
            }

            // Set Source File Generation Type
            this.rbSourceFilePerClassDTOs.Checked = true;
            this.rbOneSourceFileDTOs.Checked = (config.DTOsParams.SourceFileGenerationType == SourceFileGenerationTypeEnum.OneSourceFile);
            this.rbSourceFilePerClassAssemblers.Checked = true;
            this.rbOneSourceFileAssemblers.Checked = (config.AssemblersParams.SourceFileGenerationType == SourceFileGenerationTypeEnum.OneSourceFile);

            // Set Source File Name
            this.txtSourceFileNameDTOs.Text = config.DTOsParams.SourceFileName;
            this.txtSourceFileNameAssemblers.Text = config.AssemblersParams.SourceFileName;

            // Set Association Type
            this.rbAssociationConfigUseKeyProperty.Checked = true;
            this.rbAssociationConfigUseClassTypes.Checked = (config.DTOsParams.AssociationType == AssociationTypeEnum.ClassType);

            // Set Source File Header Comment
            this.cbCustomHeaderComment.Checked = (string.IsNullOrWhiteSpace(config.DTOsParams.SourceFileHeaderComment) == false);
            this.txtCustomHeaderComment.Text = config.DTOsParams.SourceFileHeaderComment;

            // Set Service-Ready
            this.cbServiceReadyDTOs.Checked = config.DTOsParams.DTOsServiceReady;

            // Set Generate Assemblers option
            this.cbGenerateAssemblers.Checked = config.GenerateAssemblers;

            // Set DTO identifier options
            this.rbDTOIdentifierNone.Checked = (config.DTOsParams.ClassIdentifierUse == ClassIdentifierUseEnum.None);
            this.rbDTOIdentifierPrefix.Checked = (config.DTOsParams.ClassIdentifierUse == ClassIdentifierUseEnum.Prefix);
            this.rbDTOIdentifierSuffix.Checked = (config.DTOsParams.ClassIdentifierUse == ClassIdentifierUseEnum.Suffix);
            this.txtDTOIdentifierWord.Text = config.DTOsParams.ClassIdentifierWord;

            // Set Assembler identifier options
            this.rbAssemblerIdentifierNone.Checked = (config.AssemblersParams.ClassIdentifierUse == ClassIdentifierUseEnum.None);
            this.rbAssemblerIdentifierPrefix.Checked = (config.AssemblersParams.ClassIdentifierUse == ClassIdentifierUseEnum.Prefix);
            this.rbAssemblerIdentifierSuffix.Checked = (config.AssemblersParams.ClassIdentifierUse == ClassIdentifierUseEnum.Suffix);
            this.txtAssemblerIdentifierWord.Text = config.AssemblersParams.ClassIdentifierWord;

            if (showWarnings == true)
            {
                // Check Warnings
                if (warnings.Length > 0)
                {
                    // Show warning message
                    MessageBox.Show(string.Format(Resources.Warning_WarningsWhenLoadingConfiguration, warnings),
                        Resources.Warning_Caption, MessageBoxButtons.OK, MessageBoxIcon.Warning);
                }
            }

            // Return. True if EDMX Source match, DTOs Target Project match, Assemblers Target Project match. False otherwise.
            return (edmxSourceFound && dtosProjectFound && assemblersProjectFound);
        }

        /// <summary>
        /// Loads the latest configuration used by the user.
        /// </summary>
        private void LoadLatestConfiguration()
        {
            try
            {
                // Temp config file exists?
                if (File.Exists(ConfigurationHelper.TempFilePath))
                {
                    // Load latest configuration
                    bool showWarnings = false;
                    bool edmxAndTargetProjectsFound = this.LoadConfiguration(ConfigurationHelper.TempFilePath, showWarnings);

                    if (edmxAndTargetProjectsFound)
                    {
                        // Validate generation process
                        this.ValidateGeneration();

                        // Show OK message
                        VisualStudioHelper.SetStatusBarMessage(Resources.Info_LatestConfigLoaded);
                    }
                }
            }
            catch (Exception ex)
            {
                this.ManageException(ex);
            }
        }

        #endregion Methods

    }
}